﻿using System.Collections.Generic;
using System.Linq;
using Fee.Searchers;
using Fee.VendorMatchers;
using Identity;
using Microsoft.EntityFrameworkCore;

namespace Fee.Stores.Ef
{
    public class VendorMatcherStore<T> : IVendorMatcherStore<T> where T : FeeDbContext
    {
        private readonly T _context;

        public VendorMatcherStore(T context)
        {
            _context = context;
        }

        public ConstructionVendorMatcher GetImple(District district, StationType? stationType, int year,
            ConstructionType constructionType)
        {
            return _context.Set<ConstructionVendorMatcher>().FirstOrDefault(f =>
                (district == null || f.District.Id == district.Id)
                &&
                (stationType == null || f.StationType == stationType)
                &&
                f.ConstructionType == constructionType
                &&
                f.Year == year
            );
        }

        public DesignVendorMatcher GetDesign(District district, int year, ConstructionType constructionType)
        {
            return _context.Set<DesignVendorMatcher>().FirstOrDefault(f =>
                district == null && f.District.Id == district.Id
                                 &&
                                 f.ConstructionType == constructionType
                                 &&
                                 f.Year == year
            );
        }

        public SupervisorVendorMatcher GetSupervisor(District district, int year, ConstructionType constructionType)
        {
            return _context.Set<SupervisorVendorMatcher>().FirstOrDefault(f =>
                district == null && f.District.Id == district.Id
                                 &&
                                 f.ConstructionType == constructionType
                                 &&
                                 f.Year == year
            );
        }

        public IEnumerable<VendorMatcher> List(VendorMatcherSearcher searcher, out int total)
        {
            var query = _context.VendorMatchers
                .Where(f =>
                    (searcher.ContractType == null || f.ContractType == searcher.ContractType.Value)
                    &&
                    (searcher.ConstructionType == null || f.ConstructionType == searcher.ConstructionType.Value)
                    && (searcher.District == null || searcher.District.Id == f.District.Id)
                    && (searcher.Vendor == null || searcher.Vendor.Id == f.Vendor.Id)
                );
            total = query.Count();
            return query
                .Include(_ => _.District).Include(_ => _.Vendor)
                .Skip(searcher.GetSkip())
                .Take(searcher.GetTake()).ToList();
        }

        public T1 GetById<T1>(int id) where T1 : VendorMatcher
        {
            return _context.Set<T1>().FirstOrDefault(f => f.Id == id);
        }

        public IEnumerable<VendorMatcher> GetByDistricts(int year, IEnumerable<int?> districtIds)
        {
            var query = from matcher in _context.VendorMatchers.Include(_ => _.District).Include(_ => _.Vendor)
                        where matcher.Year == year && districtIds.Contains(matcher.District.Id)
                        select matcher;
            return query.ToList();
        }
    }
}